package ochart.core
{
	import flash.display.CapsStyle;
	import flash.display.LineScaleMode;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.TextField;
	
	import ochart.elements.bars.BarBase;
	
	public class FPS extends Sprite
	{
		private var _height:Number = 50;

		override public function get height():Number
		{
			return _height;
		}

		override public function set height(value:Number):void
		{
			_height = value;
			
			resize();
		}

		private var _width:Number = 60;

		override public function get width():Number
		{
			return _width;
		}

		override public function set width(value:Number):void
		{
			_width = value;
			
			resize();
		}
		
		private var _padding:Number = 2;

		public function get padding():Number
		{
			return _padding;
		}

		public function set padding(value:Number):void
		{
			_padding = value;
		}

		private var _backgroundAlpha:Number = 0.3;

		public function get backgroundAlpha():Number
		{
			return _backgroundAlpha;
		}

		public function set backgroundAlpha(value:Number):void
		{
			if(value < 0 || value > 1)
			{
				return;
			}
			_backgroundAlpha = value;
			
			resize();
		}

		private var _backgroundColor:uint = 0xffffff;

		public function get backgroundColor():uint
		{
			return _backgroundColor;
		}

		public function set backgroundColor(value:uint):void
		{
			_backgroundColor = value;
			
			resize();
		}

		
		private var _enable:Boolean = false;

		public function get enable():Boolean
		{
			return _enable;
		}

		public function set enable(value:Boolean):void
		{
			_enable = value;
			
			visible = _enable;
			if(_enable)
			{
				addEventListener(Event.ENTER_FRAME, onEnterFrame);
			}
			else
			{
				removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			}
		}
		
		public var fps:int = 0;
		private var fpsTime:Number = 0;
		private var fpsArray:Array = [];
		private var maxFPSCount:int = 1000;
		private var fpsTextField:TextField = null;
		
		private var _textSize:Number = 15;

		public function get textSize():Number
		{
			return _textSize;
		}

		public function set textSize(value:Number):void
		{
			_textSize = value;
			
			initChart = false;
			resize();
		}

		private var _textFont:String = "Arial";

		public function get textFont():String
		{
			return _textFont;
		}

		public function set textFont(value:String):void
		{
			_textFont = value;
			
			initChart = false;
			resize();
		}
		
		private var initChart:Boolean = false;
		private var chart:Sprite = null;
		private var chartHeight:Number = 0;
		private var chartWidth:Number = 0;
		private var _chartMax:Number = 30;

		public function get chartMax():Number
		{
			return _chartMax;
		}

		public function set chartMax(value:Number):void
		{
			_chartMax = value;
			
			resize();
		}

		private var _chartBackground:Sprite = null;

		public function get chartBackground():Sprite
		{
			return _chartBackground;
		}

		public function set chartBackground(value:Sprite):void
		{
			_chartBackground = value;
			
			resize();
		}

		private var _chartBackgroundAlpha:Number = 0.8;

		public function get chartBackgroundAlpha():Number
		{
			return _chartBackgroundAlpha;
		}

		public function set chartBackgroundAlpha(value:Number):void
		{
			if(value < 0 || value > 1)
			{
				return;
			}
			
			_chartBackgroundAlpha = value;
			
			resize();
		}

		private var _chartBackgroundColor:uint = 0x1a6390;

		public function get chartBackgroundColor():uint
		{
			return _chartBackgroundColor;
		}

		public function set chartBackgroundColor(value:uint):void
		{
			_chartBackgroundColor = value;
			
			resize();
		}

		private var _chartBarAlpha:Number = 0.8;

		public function get chartBarAlpha():Number
		{
			return _chartBarAlpha;
		}

		public function set chartBarAlpha(value:Number):void
		{
			if(value < 0 || value > 1)
			{
				return;
			}
			
			_chartBarAlpha = value;
			
			resize();
		}

		private var _chartBarColor:uint = 0x91cc40;

		public function get chartBarColor():uint
		{
			return _chartBarColor;
		}

		public function set chartBarColor(value:uint):void
		{
			_chartBarColor = value;
			
			resize();
		}

		private var _chartBarWidth:Number = 2;

		public function get chartBarWidth():Number
		{
			return _chartBarWidth;
		}

		public function set chartBarWidth(value:Number):void
		{
			_chartBarWidth = value;
			
			resize();
		}

		private var _chartBarGap:Number = 0;

		public function get chartBarGap():Number
		{
			return _chartBarGap;
		}

		public function set chartBarGap(value:Number):void
		{
			_chartBarGap = value;
			
			resize();
		}

		
		public function FPS()
		{
			super();
			
			fpsTextField = new TextField();
			fpsTextField.mouseEnabled = false;
			fpsTextField.selectable = false;
			addChild(fpsTextField);
			
			chartBackground = new Sprite();
			addChild(chartBackground);
			
			chart = new Sprite();
			addChild(chart);
			
			resize();
		}
		
		protected function onEnterFrame(event:Event):void
		{
			fps++;
			var currentTime:Number = new Date().getTime();
			if(currentTime - fpsTime > 1000)
			{
				if(fpsArray.length > maxFPSCount)
				{
					fpsArray.shift();
				}
				fpsArray.push(fps);
				if(enable && fpsTextField)
				{
					var color:uint = 0;
					if(fps < 5)
					{
						color = 0xff0000;
					}
					else if(fps < 10)
					{
						color = 0xee00ff;
					}
					else if(fps < 15)
					{
						color = 0xff9900;
					}
					else if(fps < 20)
					{
						color = 0x0044ff;
					}
					else
					{
						color = 0x000000;
					}
					fpsTextField.textColor = color;
					fpsTextField.htmlText = "<font size='" + textSize + "' face='" + textFont + "'>FPS:" + fps + "</font>";
					if(!initChart)
					{
						initChart = true;
						resize();
					}
					drawChart();
				}
				fps = 0;
				fpsTime = currentTime;
			}
		}
		
		private function drawChart():void
		{
			if(!chart)
			{
				return;
			}
			var count:int = Math.ceil(chartWidth / (chartBarWidth + chartBarGap));
			var index:int = 0;
			var fpsArrayLength:int = fpsArray.length;
			var step:Number = chartHeight / chartMax;
			
			chart.graphics.clear();
			chart.graphics.lineStyle(chartBarWidth, chartBarColor, chartBarAlpha, true, LineScaleMode.NONE, CapsStyle.NONE);
			while(index < count)
			{
				var fps:int = fpsArray[fpsArrayLength - index - 1];
				var fromX:Number = chartWidth - (chartBarWidth * (index + 0.5)) - (chartBarGap * index);
				var fromY:Number = chartHeight;
				var toX:Number = fromX;
				var toY:Number = chartHeight - step * fps;
				chart.graphics.moveTo(fromX, fromY);
				chart.graphics.lineTo(toX, toY);
				index++;
			}
		}
		
		public function resize():void
		{
			this.graphics.clear();
			this.graphics.beginFill(backgroundColor, backgroundAlpha);
			this.graphics.drawRect(0, 0, width, height);
			this.graphics.endFill();
			
			fpsTextField.x = padding;
			fpsTextField.y = padding;
			fpsTextField.width = width - (padding * 2);
			
			if(chart && initChart)
			{
				chartHeight = height - (padding * 2) - fpsTextField.textHeight - 5;
				chartWidth = width - (padding * 2);
				chart.x = padding;
				chart.y = height - padding - chartHeight;
				
				var chartMask:Sprite = new Sprite();
				chartMask.x = chart.x;
				chartMask.y = chart.y;
				chartMask.graphics.beginFill(0);
				chartMask.graphics.drawRect(0, 0, chartWidth, chartHeight);
				chartMask.graphics.endFill();
				chart.mask = chartMask;
				
				chartBackground.x = chart.x;
				chartBackground.y = chart.y;
				chartBackground.graphics.clear();
				chartBackground.graphics.beginFill(chartBackgroundColor, chartBackgroundAlpha);
				chartBackground.graphics.drawRect(0, 0, chartWidth, chartHeight);
				chartBackground.graphics.endFill();
				
				drawChart();
			}
		}
	}
}